#include "ADUWater.h"
#include "ADUConfig.h"
#include "ADUGameManager.h"

Water::Water(int _count,float _height){

    int _numVer;

    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    float centerX = origin.x + visibleSize.width/2;
    float centerY = origin.y + visibleSize.height/2;

    mStartX = origin.x;
    mVerticesSpacing = visibleSize.width*1.2/_count;

    mNormal = b2Vec2(0,1);

    mWorld = GameManager::getInstance()->mWorld;


    mControllerDef = new b2BuoyancyControllerDef();
    mControllerDef->normal.Set(0,1.0f);
    mControllerDef->density =10.0f;
    mControllerDef->offset = _height/PTM_RATIO;
    mControllerDef->useWorldGravity = true;
    mControllerDef->useDensity = true;
    mControllerDef->linearDrag = 7.0f;
    mControllerDef->angularDrag = 2.0f;

    mController = (b2BuoyancyController*)mWorld->CreateController(mControllerDef);

    mDrawer = DrawNode::create();

    mCount = _count;
    mHeight = _height;
    _numVer = 2+mCount;

    mVertices = new Vec2[_numVer];
    mSpring= new Spring[mCount];




    for (int i = 2; i<_numVer;i++){
       mVertices[i] = Vec2(mStartX+(_numVer-i-1)*mVerticesSpacing,mHeight);
        mSpring[i-2].SetOriginPos(mVertices[i]);
        mSpring[i-2].SetId(i-2);

    }

    mVertices[0] = Vec2(mVertices[_numVer-1].x,mBottom);
    mVertices[1] = Vec2(mVertices[2].x,mBottom);

}

Water::~Water(){

}

void Water::AddBody(b2Body* body){
	mController->AddBody(body);
}


void Water::RemoveBody(b2Body* body){
	mController->AddBody(body);
}

void Water::Clear(){
	mController->Clear();
}



void Water::Splash(float speed,int id){
	mSpring[id].mSpeed = speed;
}

void Water::OnUpdate(float dt){
    int _numVer;
    _numVer = 2 + mCount;

    for(int e = 0; e < mCount; e++){
       mSpring[e].OnUpdate(dt);
    }

    float lDeltas[mCount];
    float rDeltas[mCount];

    for (int i = 0; i < mCount; i++)
    {
        if (i > 0)
        {
        	lDeltas[i] = mSpread * (mSpring[i].mY - mSpring [i - 1].mY);
            mSpring[i - 1].mSpeed += 2*lDeltas[i];
        }
        if (i < mCount - 1)
        {
        	rDeltas[i] = mSpread * (mSpring[i].mY - mSpring [i + 1].mY);
            mSpring[i + 1].mSpeed += 2*rDeltas[i];
        }
    }

    for (int i = 0; i < mCount; i++)
    {
        if (i > 0){
        	mSpring[i - 1].mY += lDeltas[i];
        	mSpring[i - 1].LoadBodyPos();
        }
        if (i < mCount - 1){
        	mSpring[i + 1].mY += rDeltas[i];
        	mSpring[i + 1].LoadBodyPos();
        }
    }


    for (int i = 2; i<_numVer;i++){
        mVertices[i] = mSpring[i-2].GetPos();
    }

    mDrawer->clear();

    mDrawer->drawPolygon(mVertices, _numVer, mFilledColor, 1.0f, mBoderColor);
}

DrawNode* Water::GetDrawer(){
    return mDrawer;
}

void Water::SetupColor(Color4F _fill, Color4F _boder){
    mBoderColor = _boder;
    mFilledColor = _fill;
}
